#include "comparator.h"

#include <no_destructor.h>

namespace minidb
{

class BytewiseComparatorImpl : public Comparator
{
public:
    BytewiseComparatorImpl() = default;

    const char *Name() const override
    {
        return "minidb.BytewiseComparator";
    }

    int Compare(const Slice &a, const Slice &b) const override
    {
        return a.compare(b);
    }

    void FindShortestSeparator(std::string *start,
                               const Slice &limit) const override
    {
        std::size_t min_length = std::min(start->size(), limit.size());
        std::size_t diff_index = 0;
        while ((diff_index < min_length) && ((*start)[diff_index] == limit[diff_index]))
        {
            ++diff_index;
        }

        if (diff_index >= min_length)
        {
            // Do not shorten if one string is a prefix of the other
        }
        else
        {
            uint8_t diff_byte = static_cast<uint8_t>((*start)[diff_index]);
            if (diff_byte < static_cast<uint8_t>(0xff) && diff_byte + 1 < static_cast<uint8_t>(limit[diff_index]))
            {
                (*start)[diff_index]++;             // 第diff_index个元素的值+1
                start->resize(diff_index + 1);      // diff_index索引，索引+1为长度
                assert(Compare(*start, limit) < 0); // slice::compare，字典序相同时，比较长度
            }
        }
    }

    void FindShortSuccessor(std::string *key) const override
    {
        std::size_t n = key->size();
        for (std::size_t i = 0; i < n; ++i)
        {
            const uint8_t byte = (*key)[i];
            if (byte != static_cast<uint8_t>(0xff))
            {
                (*key)[i] = byte + 1;
                key->resize(i + 1);
                return;
            }
        }
    }
};

const Comparator *BytewiseComparator()
{
    static NoDestructor<BytewiseComparatorImpl> singleton; 
    return singleton.get();
}
} // namespace minidb